package org.ccay.core.orm.impl;

import java.util.HashMap;
import java.util.Map;

import javax.inject.Named;

import org.w3c.dom.Element;

import org.ccay.core.base.PageVO;
import org.ccay.core.log.ILogger;
import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.orm.ITagHandler;
import org.ccay.core.util.StringUtil;

/**
 * 用来处理&lt;addOrderBy &gt;Tag, 解析后, 调用IProgramSqlBuilder接口
 * 
 * @see org.ccay.security.service.internal.IProgramSqlBuilder
 * 
 * @since 2011-12-14
 */
@Named("addOrderByTagHandler")
public class AddOrderByTagHandler implements ITagHandler {
	private static final ILogger log = CcayLoggerFactory.getLogger(AddOrderByTagHandler.class);
	/*
	 * 处理&lt;addOrderBy &gt;标签, 
	 * 
	 * @see org.ccay.orm.ITagHandler#handle(org.w3c.dom.Element,
	 *      java.lang.String, java.lang.Object)
	 */
	public String handle(Element ele, String tag, Object parameterObject) {
		// 解析orderBy2Fields属性
		String orderBy2Fields = ele.getAttribute("orderBy2Fields");
		String[] fields = orderBy2Fields.split(",");

		Map<String, String> orderBy2FieldMap = new HashMap<String, String>(
				fields.length);
		for (String field : fields) {

			String[] fieldName = field.split(":");
			if (fieldName == null || fieldName.length != 2) {
				throw new IllegalArgumentException(
						"The field should be in a pair, orderBy2Fields: "
								+ orderBy2Fields);
			}
			orderBy2FieldMap.put(fieldName[0], fieldName[1]);
		}
		
		String orderBy = this.findOrderBy(parameterObject);
		
		String orderbyStr = this.buildSql(orderBy2FieldMap,orderBy);
		orderbyStr = this.getPrependOrderbyStr(ele,orderbyStr);
		return orderbyStr;

	}
	/**
	 * 构建sql语句
	 * @param prepend
	 * @param orderBy2FieldMap
	 * @param orderByStr
	 * @return
	 * Created：2013-3-28
	 * @author chaowangbang
	 */
	private String buildSql(Map<String, String> orderBy2FieldMap,String orderByStr){
		StringBuilder sql = new StringBuilder("");
		//如果是默认的 那么不处理
		if("default".equalsIgnoreCase(orderByStr)){
			return sql.toString();
		}
		//如果orderby是空的 直接返回
		if(StringUtil.isNullOrEmpty(orderByStr)){
			return sql.toString();
		}
		String[] orderBys = orderByStr.split(",");
		//迭代 查找对应的orderby字段  并组装排序
		for (String order : orderBys) {
			String[] orderName = order.split(" ");
			if (orderName == null || orderName.length != 2) {
				throw new IllegalArgumentException(
						"The field should be in a pair, orderByStr: "
								+ order);
			}
			if(this.checkOrderby(orderBy2FieldMap,orderName)){
				sql.append(" " + orderBy2FieldMap.get(orderName[0])+ " " + orderName[1]+",");
			}else{
				log.warn(order + " field is not pair");
			}
		}
		//删除最后一个,
		if(sql.toString().endsWith(",")){
			sql.delete(sql.length()-1, sql.length());
		}
		return sql.toString();
	}
	/**
	 * 检查  是否符合规则
	 * @param orderBy2FieldMap
	 * @param orderName
	 * @return
	 * Created：2013-4-12
	 * @author chaowangbang
	 */
	private boolean checkOrderby(Map<String, String> orderBy2FieldMap,String[] orderName){
		if(orderBy2FieldMap.get(orderName[0])!=null 
				&& ("desc".equalsIgnoreCase(orderName[1]) || "asc".equalsIgnoreCase(orderName[1])) ){
			return true;
		}
		return false;
	}
	/**
	 * 判断是否有 pageVO 参数 并返回对象
	 * @param pageVO
	 * @param parameter
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private String findOrderBy(Object parameter) {
		if(null == parameter ){
			return null;
		}
		PageVO page = null;
		//这个的情况比较多 优先执行这个代码
		if(parameter instanceof Map ){
			Map<Object, Object> parameterMap = (Map<Object, Object>)parameter;
			for(Map.Entry<Object, Object> entry:parameterMap.entrySet()){
				if (entry.getValue() instanceof PageVO) {
					page = (PageVO) entry.getValue();
					return page.getOrderBy();
				}
			}
		}
		
		//后面再考虑单个参数的问题
		if(parameter instanceof PageVO){
			page =  (PageVO) parameter;
			return page.getOrderBy();
		}
		return null;
	}
	/**
	 * 获取最终的order by  语句
	 * @param prepend
	 * @param orderbyStr
	 * @return
	 * Created：2013-4-2
	 * @author chaowangbang
	 */
	private String getPrependOrderbyStr(Element ele,String orderbyStr){
		//pend  连接
		String prepend = ele.getAttribute("prepend");
		if(StringUtil.isNullOrEmpty(prepend)){
			prepend="";
		}
		//结尾
		String suffix = ele.getAttribute("suffix");
		if(StringUtil.isNullOrEmpty(suffix)){
			suffix="";
		}
		if(StringUtil.isNullOrEmpty(orderbyStr)){
			return "" ;
		}
		return prepend + " " + orderbyStr + suffix;
	}
}
